21 #define foreach(x, v) for (typeof (v).begin() x = (v).begin(); x != (v).end(); ++x)
22 #define For(i, a, b) for (int i=(a); i<(b); ++i)
23 #define D(x) cout << #x " is " << x << endl
25 /////////////// Maximum flow for sparse graphs ///////////////
26 /////////////// Complexity: O(V * E^2) ///////////////
30 Call initialize_max_flow();
31 Create graph using add_edge(u, v, c);
32 max_flow(source, sink);
34 WARNING: The algorithm writes on the cap array. The capacity
35 is not the same after having run the algorithm. If you need
36 to run the algorithm several times on the same graph, backup
41 // Maximum number of nodes
42 const int MAXN
= 51 * 51 * 2;
43 // Maximum number of edges
44 // IMPORTANT: Remember to consider the backedges. For
45 // every edge we actually need two! That's why we have
46 // multiply by two at the end.
47 const int MAXE
= MAXN
* 6 * 2;
48 const int oo
= INT_MAX
/ 4;
56 Builds a directed edge (u, v) with capacity c.
57 Note that actually two edges are added, the edge
58 and its complementary edge for the backflow.
60 int add_edge(int u
, int v
, int c
){
61 adj
[current_edge
] = v
;
62 cap
[current_edge
] = c
;
63 next
[current_edge
] = first
[u
];
64 first
[u
] = current_edge
++;
66 adj
[current_edge
] = u
;
67 cap
[current_edge
] = 0;
68 next
[current_edge
] = first
[v
];
69 first
[v
] = current_edge
++;
72 void initialize_max_flow(){
74 memset(next
, -1, sizeof next
);
75 memset(first
, -1, sizeof first
);
81 //arrived_by[i] = The last edge used to reach node i
82 int find_augmenting_path(int src
, int snk
){
84 Make a BFS to find an augmenting path from the source
85 to the sink. Then pump flow through this path, and
86 return the amount that was pumped.
88 memset(arrived_by
, -1, sizeof arrived_by
);
93 while (h
< t
&& arrived_by
[snk
] == -1){ //BFS
95 for (int e
= first
[u
]; e
!= -1; e
= next
[e
]){
97 if (arrived_by
[v
] == -1 && cap
[e
] > 0){
99 incr
[v
] = min(incr
[u
], cap
[e
]);
105 if (arrived_by
[snk
] == -1) return 0;
108 int neck
= incr
[snk
];
110 //Remove capacity from the edge used to reach
111 //node "cur", and add capacity to the backedge
112 cap
[arrived_by
[cur
]] -= neck
;
113 cap
[arrived_by
[cur
] ^ 1] += neck
;
114 //move backwards in the path
115 cur
= adj
[arrived_by
[cur
] ^ 1];
120 int max_flow(int src
, int snk
){
122 while ((neck
= find_augmenting_path(src
, snk
)) != 0){
129 inline int in(int u
){ return 2*u
; }
130 inline int out(int u
){ return 2*u
+ 1; }
131 inline int number(int r
, int c
){ return r
* cols
+ c
; }
133 void print_edges(int u
){
134 printf("Edges going out from %d:\n", u
);
135 for (int e
= Flow::first
[u
]; e
!= -1; e
= Flow::next
[e
]){
136 printf("(v = %d, cap = %d)\n", Flow::adj
[e
], Flow::cap
[e
]);
142 for(scanf("%d", &cases
); cases
--; ){
144 if (scanf("%d %d %d", &rows
, &cols
, &banks
) != 3) break;
146 int source
= rows
* cols
, sink
= source
+ 1;
148 Flow::initialize_max_flow();
150 for (int k
=0; k
<banks
; ++k
){
152 scanf("%d %d", &r
, &c
);
154 Flow::add_edge(out(number(r
, c
)), in(sink
), 1);
157 for (int i
=0; i
<rows
; ++i
){
158 for (int j
=0; j
<cols
; ++j
){
159 if (i
== 0 || i
== rows
- 1 || j
== 0 || j
== cols
- 1){ //node lies on the border
160 Flow::add_edge(out(source
), in(number(i
, j
)), 1);
163 Flow::add_edge(out(number(i
, j
)), in(number(i
-1, j
)), 1);
166 Flow::add_edge(out(number(i
, j
)), in(number(i
+1, j
)), 1);
169 Flow::add_edge(out(number(i
, j
)), in(number(i
, j
-1)), 1);
172 Flow::add_edge(out(number(i
, j
)), in(number(i
, j
+1)), 1);
177 for (int i
=0; i
<rows
; ++i
){
178 for (int j
=0; j
<cols
; ++j
){
179 Flow::add_edge(in(number(i
, j
)), out(number(i
, j
)), 1);
182 Flow::add_edge(in(source
), out(source
), Flow::oo
);
183 Flow::add_edge(in(sink
), out(sink
), Flow::oo
);
186 printf("in nodes:\n");
187 for (int i=0; i<rows; ++i){
188 for (int j=0; j<cols; ++j){
189 print_edges(in(number(i, j)));
192 printf("out nodes:\n");
193 for (int i=0; i<rows; ++i){
194 for (int j=0; j<cols; ++j){
195 print_edges(out(number(i, j)));
199 print_edges(in(source));
200 print_edges(out(source));
202 print_edges(in(sink));
203 print_edges(out(sink));
206 int f
= Flow::max_flow(in(source
), out(sink
));
208 printf("%s\n", f
== banks
? "possible" : "not possible");